﻿#include "mycammerwidget.h"
#include "ui_mycammerwidget.h"
#include <QDebug>

MyCammerWidget::MyCammerWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::MyCammerWidget)
    , currentAcquisitionMode(AcquisitionMode::Continuous)
{
    ui->setupUi(this);

    //注册自定义数据类型
    qRegisterMetaType<uint64_t>("uint64_t");
}

MyCammerWidget::~MyCammerWidget()
{
    //关闭线程
    if(thread1->isRunning() || thread2->isRunning())
    {
        //终止线程
        stopMyThread();
    }

    delete ui;
}

//退出线程函数
void MyCammerWidget::stopMyThread()
{
    //断开槽函数
    disconnect(this, SIGNAL(signalDisplayFPSSet(int)), displayThread, SLOT(DisplayFPSSet(int)));
    disconnect(displayThread, SIGNAL(signalShowImage(uint8_t*, int, int, uint64_t)), this, SLOT(ShowImage(uint8_t*, int, int, uint64_t)));

    //停止捕获图像
    if(getThread)
    {
        getThread->stop();
    }

    //退出捕获图像线程
    thread1->quit();

    if(displayThread)
    {
        displayThread->stop();
    }
    thread2->quit();
}

//设置相机
void MyCammerWidget::SetCamera(const QString& strKey)
{
    CSystem &systemObj = CSystem::getInstance();
    m_CameraPtr = systemObj.getCameraPtr(strKey.toStdString().c_str());
}

// 切换采集方式
bool MyCammerWidget::CameraChangeAcquisitionMode(AcquisitionMode acquisitionMode)
{
    if (NULL == m_CameraPtr)
    {
        printf("Change Acquisition fail. No camera or camera is not connected.\n");
        return false;
    }

    if (AcquisitionMode::SingleFrame == acquisitionMode)
    {
        //设置采集模式
        CEnumNode nodeAcquisitionMode(m_CameraPtr, "AcquisitionMode");
        if (false == nodeAcquisitionMode.isValid())
        {
            printf("get AcquisitionMode node fail.\n");
            return false;
        }
        if (false == nodeAcquisitionMode.setValueBySymbol("SingleFrame"))
        {
            printf("set AcquisitionMode value = SingleFrame fail.\n");
            return false;
        }
        currentAcquisitionMode = AcquisitionMode::SingleFrame;
    }
    else if (AcquisitionMode::Continuous == acquisitionMode)
    {
        //设置采集模式
        CEnumNode nodeAcquisitionMode(m_CameraPtr, "AcquisitionMode");
        if (false == nodeAcquisitionMode.isValid())
        {
            printf("get AcquisitionMode node fail.\n");
            return false;
        }
        if (false == nodeAcquisitionMode.setValueBySymbol("Continuous"))
        {
            printf("set AcquisitionMode value = Continous fail.\n");
            return false;
        }
        currentAcquisitionMode = AcquisitionMode::Continuous;
    }

    return true;
}

//打开相机
bool MyCammerWidget::CameraOpen()
{
    if (NULL == m_CameraPtr)
    {
        printf("connect camera fail. No camera.\n");
        return false;
    }

    if (true == m_CameraPtr->isConnected())
    {
        printf("camera is already connected.\n");
        return true;
    }

    if (false == m_CameraPtr->connect())
    {
        printf("connect camera fail.\n");
        return false;
    }

    return true;
}

// 关闭相机
bool MyCammerWidget::CameraClose()
{
    if (NULL == m_CameraPtr)
    {
        printf("disconnect camera fail. No camera.\n");
        return false;
    }

    if (false == m_CameraPtr->isConnected())
    {
        printf("camera is already disconnected.\n");
        return true;
    }

    if (false == m_CameraPtr->disConnect())
    {
        printf("disconnect camera fail.\n");
        return false;
    }

    return true;
}

//开始采集图像流(getframe)
bool MyCammerWidget::CameraStart()
{
    if (NULL == m_StreamSPtr)
    {
        m_StreamSPtr = CSystem::getInstance().createStreamSource(m_CameraPtr);
    }

    if (NULL == m_StreamSPtr)
    {
        return false;
    }

    if (m_StreamSPtr->isGrabbing())
    {
        return true;
    }

    if (!m_StreamSPtr->startGrabbing())
    {
        return false;
    }

    //创建捕获图像线程
    getThread = new GetFrameThread(currentAcquisitionMode, m_StreamSPtr, &m_cFrameInfolist);
    thread1 = new QThread;

    //创建显示图像线程
    displayThread = new DisplayFrameThread(currentAcquisitionMode, &m_cFrameInfolist);
    thread2 = new QThread;

    //绑定信号和槽
    connect(thread1, SIGNAL(started()), getThread, SLOT(doWork()));
    connect(thread1, SIGNAL(finished()), getThread, SLOT(deleteLater()));

    connect(this, SIGNAL(signalDisplayFPSSet(int)), displayThread, SLOT(DisplayFPSSet(int)), Qt::QueuedConnection);
    connect(displayThread, SIGNAL(signalShowImage(uint8_t*, int, int, uint64_t)), this, SLOT(ShowImage(uint8_t*, int, int, uint64_t)));
    connect(thread2, SIGNAL(started()), displayThread, SLOT(doWork()));
    connect(thread2, SIGNAL(finished()), displayThread, SLOT(deleteLater()));

    //开启线程
    getThread->moveToThread(thread1);
    displayThread->moveToThread(thread2);
    thread2->start();
    thread1->start();

    return true;
}

//停止采集
bool MyCammerWidget::CameraStop()
{
    if (m_StreamSPtr != NULL)
    {
        //流指针停止抓流
        m_StreamSPtr->stopGrabbing();

        //关闭取流线程
        if(thread1->isRunning() || thread2->isRunning())
        {
            //终止抓图线程
            stopMyThread();
        }

        m_StreamSPtr.reset();
    }

    m_cFrameInfolist.clearCFrameInfoList();

    return true;
}

//帧率设置函数
void MyCammerWidget::FPSSet(int fps)
{
    emit signalDisplayFPSSet(fps);
}

//显示图片
bool MyCammerWidget::ShowImage(uint8_t* pRgbFrameBuf, int nWidth, int nHeight, uint64_t nPixelFormat)
{
    QImage image;
    if (NULL == pRgbFrameBuf ||
        nWidth == 0 ||
        nHeight == 0)
    {
        printf("%s image is invalid.\n", __FUNCTION__);
        return false;
    }
    if (Dahua::GenICam::gvspPixelMono8 == nPixelFormat)
    {
        image = QImage(pRgbFrameBuf, nWidth, nHeight, QImage::Format_Grayscale8);
    }
    else
    {
        image = QImage(pRgbFrameBuf, nWidth, nHeight, QImage::Format_RGB888);
    }

    //将QImage的大小收缩或拉伸，与label的大小保持一致。这样label中能显示完整的图片
    QImage imageScale = image.scaled(QSize(ui->label_Pixmap->width(), ui->label_Pixmap->height()));
    QPixmap pixmap = QPixmap::fromImage(imageScale);
    ui->label_Pixmap->setPixmap(pixmap);
    free(pRgbFrameBuf);

    return true;
}

// 窗口关闭响应函数
void MyCammerWidget::closeEvent(QCloseEvent * event)
{
    if (NULL != m_StreamSPtr && m_StreamSPtr->isGrabbing())
    {
        m_StreamSPtr->stopGrabbing();
    }

    if (NULL != m_CameraPtr && m_CameraPtr->isConnected())
    {
        m_CameraPtr->disConnect();
    }
}
